home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / PARSEINFO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-05  |  20.2 KB  |  663 lines

  1. /* parseinfo.c - module to parse the pcgi info file
  2.  
  3. Copyright (c) 1998, Digital Creations, Fredericksburg, VA, USA.  All
  4. rights reserved. This software includes contributions from Jeff Bauer.
  5.  
  6. Redistribution and use in source and binary forms, with or without
  7. modification, are permitted provided that the following conditions are
  8. met:
  9.  
  10.   o Redistributions of source code must retain the above copyright
  11.     notice, this list of conditions, and the disclaimer that follows.
  12.  
  13.   o Redistributions in binary form must reproduce the above copyright
  14.     notice, this list of conditions, and the following disclaimer in
  15.     the documentation and/or other materials provided with the
  16.     distribution.
  17.  
  18.   o All advertising materials mentioning features or use of this
  19.     software must display the following acknowledgement:
  20.  
  21.       This product includes software developed by Digital Creations
  22.       and its contributors.
  23.  
  24.   o Neither the name of Digital Creations nor the names of its
  25.     contributors may be used to endorse or promote products derived
  26.     from this software without specific prior written permission.
  27.  
  28.  
  29. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS *AS IS* AND
  30. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  31. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  32. PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
  33. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  34. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  35. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  36. BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  37. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  38. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  39. IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40. */
  41.  
  42. #include "pcgi.h"
  43.  
  44. extern char **environ;
  45. extern int CloseFileDescriptors;
  46.  
  47. int pcgiAssignCloseFileDescriptors(pcgiResource *r, char *val)
  48. {
  49.     if ((CloseFileDescriptors = pcgiTruthValue(val[0]) < 0))
  50.     {
  51.         sprintf(r->errmsg, "unknown value for PCGI_CLOSE_FDS: %s", val);
  52.         return(-1);
  53.     }
  54.     return(0);
  55. }
  56.  
  57. int pcgiAssignPublisher(pcgiResource *r)
  58. {
  59.     /*
  60.     // Determine the publisher path based on the current values
  61.     // of the pcgiResource structure.
  62.     */
  63.     char *p, *pBegin, *pEnd, testdir[MAXSZ];
  64.     char combinedPaths[MAXPATH+MAXPATH+2];
  65.  
  66.     if (r->pubpath[0]) /* assignment already made, our work is done :) */
  67.     {
  68.         return(0);
  69.     }
  70.     /*
  71.     //  Look through the PCGI_INSERT_PATH directories for the publisher.
  72.     */
  73.     strcat(combinedPaths, r->insertPath);
  74.     strcat(combinedPaths, ":");
  75.     strcat(combinedPaths, r->pythonPath);
  76.  
  77.     pBegin = combinedPaths;
  78.     pEnd = pBegin + strlen(combinedPaths);
  79.     while(pBegin < pEnd)
  80.     {
  81.         p = pBegin;
  82.         do {
  83.             if (*p == ':' || *p == '\0')
  84.                 break;
  85.         } while(*p++);
  86.         strncpy(testdir, pBegin, p-pBegin);
  87.         testdir[p-pBegin] = '\0';
  88.         if ((pcgiAssignPublisherPath(testdir, r))==0)
  89.         {
  90.             return(0);
  91.         }
  92.         if (p == pBegin) 
  93.         {
  94.             pBegin++;
  95.         }
  96.         else
  97.         {
  98.             pBegin = p; 
  99.         }
  100.     }
  101.  
  102.     /*
  103.     //  Run through a gauntlet of misc. attempts to find the publisher.
  104.     */
  105.     if (r->modpath[0])
  106.     {
  107.         if ((pcgiAssignPublisherPath(r->modpath, r)) == 0)
  108.             return(0);
  109.     }
  110.     if (r->sw_info[0])
  111.     {
  112.         if ((pcgiAssignPublisherPath(r->sw_info, r)) == 0)
  113.             return(0);
  114.     }
  115.     if (r->sw_home[0])
  116.     {
  117.         if ((pcgiAssignPublisherPath(r->sw_home, r)) == 0)
  118.             return(0);
  119.     }
  120.     if (r->sw_exe[0])
  121.     {
  122.         if ((pcgiAssignPublisherPath(r->sw_exe, r)) == 0)
  123.             return(0);
  124.     }
  125.     return(-1);
  126. }
  127.  
  128. #define PubCount 4  /* variations on a publisher name */
  129.  
  130. int pcgiAssignPublisherPath(char *path, pcgiResource *r)
  131. {
  132.     /*
  133.     // Attempt to assign the path to the publisher, return 0 for success,
  134.     // otherwise -1.
  135.      */
  136.     char *p[PubCount];
  137.     char testdir[MAXSZ], pubpath[MAXSZ];
  138.     int i, len;
  139.     struct stat statbuf;
  140.  
  141.     p[0] = PUBLISHER_NAME_1;
  142.     p[1] = PUBLISHER_NAME_2;
  143.     p[2] = PUBLISHER_NAME_3;
  144.     p[3] = PUBLISHER_NAME_4;
  145.  
  146.     strcpy(testdir, path); 
  147.     len = strlen(testdir);
  148.     if (len < 1 || (MAXSZ <= len + strlen(PUBLISHER_NAME_1) + 1))
  149.     {
  150.         return(-1);
  151.     }
  152.     if (PATHSEP == testdir[len-1]) 
  153.     { 
  154.         testdir[len-1] = '\0'; /* truncate trailing slash */
  155.     }
  156.  
  157.     if (stat(testdir, &statbuf) == -1)
  158.     {
  159.         return(-1); /* unable to stat path */
  160.     }
  161.  
  162.     if (!(statbuf.st_mode & S_IFDIR))
  163.     {
  164.         /* 
  165.         // If the supplied path was not a directory, assume it was
  166.         // a file and get the directory portion of it.
  167.         */
  168.         while(len > 0)
  169.         {
  170.             if (PATHSEP == testdir[--len])
  171.             {
  172.                testdir[len] = '\0';
  173.                break;
  174.             }
  175.         }
  176.         if (len < 1) { return(-1); }
  177.     }
  178.  
  179.     for (i=0; i < PubCount; i++)
  180.     {
  181.         sprintf(pubpath, "%s%c%s", testdir, PATHSEP, p[i]);
  182.         if (stat(pubpath, &statbuf) != -1)
  183.         {
  184.             if (statbuf.st_mode & S_IREAD)
  185.             {
  186.                 strcpy(r->pubpath, pubpath);
  187.                 return(0);
  188.             } 
  189.         }
  190.     }
  191.     return(-1);
  192. }
  193.  
  194. int pcgiEnvironmentToResourceAssignment(pcgiResource *r)
  195. {
  196.     /*
  197.     // Read in the environment and make whatever appropriate assignments
  198.     // prior to reading in the pcgi info file.  Values from the pcgi info
  199.     // override environment settings.
  200.     //
  201.     // This function is necessary because the user may want to set
  202.     // an enviroment variable globally (e.g. PCGI_PUBLISHER from 
  203.     // a httpd .conf file),
  204.     */
  205.     char **env;
  206.     char *p = NULL;
  207.     char buf[MAXSZ];
  208.     char *nam, *val;
  209.  
  210.     for (env=environ; *env != 0; env++)
  211.     {
  212.         if (strlen(*env) >= MAXSZ)
  213.         {
  214.             continue;
  215.         }
  216.         strcpy(buf, *env);
  217.  
  218.         if ((p = strchr(buf,'=')) != NULL)
  219.         {
  220.             *p++ = '\0';
  221.             nam = buf;
  222.             val = p;
  223.             if((strncmp(nam, "SOFTWARE_", strlen("SOFTWARE_")))==0)
  224.             {
  225.                 if((strcmp(nam,"SOFTWARE_NAME"))==0)
  226.                     strcpy(r->sw_name, val);
  227.                 else if((strcmp(nam,"SOFTWARE_HOME"))==0)
  228.                     strcpy(r->sw_home, val);
  229.                 else if((strcmp(nam,"SOFTWARE_EXE"))==0)
  230.                     strcpy(r->sw_exe, val);
  231.             }
  232.             if((strcmp(nam,"PYTHONPATH"))==0)
  233.             {
  234.                 /* TODO: check strlen against MAXPATH */
  235.                 strcpy(r->pythonPath, val);
  236.             }
  237.             else if((strncmp(nam, "PCGI_", strlen("PCGI_")))==0)
  238.             {
  239.                 if ((strcmp(nam,"PCGI_CLOSE_FDS"))==0)
  240.                 {
  241.                     if ((pcgiAssignCloseFileDescriptors(r, val)) < 0)
  242.                         return(-1);
  243.                 }
  244.                 else if ((strcmp(nam,"PCGI_DISPLAY_ERRORS"))==0)
  245.                       r->displayErrors = pcgiTruthValue(val[0]);
  246.                 else if ((strcmp(nam,"PCGI_ERROR_LOG"))==0)
  247.                     strcpy(r->errlog, val);
  248.                 else if ((strcmp(nam,"PCGI_EXE"))==0)
  249.                     strcpy(r->sw_exe, val);
  250.                 else if ((strcmp(nam,"PCGI_HOST"))==0)
  251.                     strcpy(r->sockhost, val);
  252.                 else if ((strcmp(nam,"PCGI_INSERT_PATH"))==0 ||
  253.                          (strcmp(nam,"PCGI_WORKING_DIR"))==0)
  254.                 {
  255.                     if (strlen(val) >= MAXPATH)
  256.                     {
  257.                         strcpy(r->errmsg, "pcgiEnvironmentToResourceAssignment() length exceeds MAXPATH");
  258.                         return(-1);
  259.                     }
  260.                     strcpy(r->insertPath, val);
  261.                 }
  262.                 else if ((strcmp(nam,"PCGI_MODULE_PATH"))==0)
  263.                     strcpy(r->modpath, val);
  264.                 else if ((strcmp(nam,"PCGI_NAME"))==0)
  265.                     strcpy(r->sw_name, val);
  266.                 else if ((strcmp(nam,"PCGI_PID_FILE"))==0)
  267.                     strcpy(r->procpath, val);
  268.                 else if ((strcmp(nam,"PCGI_PORT"))==0)
  269.                     r->sockport = atoi(val);
  270.                 else if ((strcmp(nam,"PCGI_PUBLISHER"))==0)
  271.                     strcpy(r->pubpath, val);
  272.                 else if ((strcmp(nam,"PCGI_SOCKET_FILE"))==0)
  273.                     strcpy(r->sockpath, val);
  274.             }
  275.         }
  276.     }
  277.  
  278.     return(0);
  279. }
  280.  
  281. /*
  282. // pcgiParseInfo: Parse info file named in resource->sw_info
  283. */
  284. int pcgiParseInfo(pcgiResource *r)
  285. {   
  286.     FILE *f;
  287.     char buf[256];
  288.     char *v=NULL;
  289.     char *p=NULL;
  290.     struct stat statbuf;
  291.     int _newStyleDirectives = 0;
  292.     int _oldStyleLineCount = 0;
  293.     enum { oldStyleSocketFile, oldStyleProcessIdFile, oldStyleWorkDir, oldStyleModPath };
  294.  
  295.     if ((pcgiEnvironmentToResourceAssignment(r)) < 0)
  296.     {
  297.         if (!r->errmsg[0])
  298.             strcpy(r->errmsg, "pcgiEnvironmentToResourceAssignment() error");
  299.         return(-1);
  300.     }
  301.  
  302.     if((f=fopen(r->sw_info, "r")) == NULL)
  303.     {
  304.         sprintf(r->errmsg, "unable to open info file: %s", r->sw_info);
  305.         return(-1);
  306.     }
  307.  
  308.     pcgiPutNameValueInEnvironment("PCGI_INFO_FILE", r->sw_info);
  309.  
  310.     while(fgets(buf, 255, f) != NULL)
  311.     {   
  312.       /* XXX - TODO: trim leading, trailing whitespace */
  313.  
  314. #ifdef WIN32
  315.         amendPathSeparators(buf);
  316. #endif
  317.         if((buf[0] != '#') && (buf[0] != '\n'))
  318.         {   
  319.             p=(strrchr(buf,'\0')-sizeof(char));
  320.             while((p >= buf) && (isspace(*p)))
  321.             {  
  322.                 *p=0;
  323.                 p--;
  324.             }
  325.  
  326.             if ((p=strchr(buf,'=')) != NULL)
  327.             {
  328.                 _newStyleDirectives = 1;
  329.                 if ((pcgiPutEnvironment(buf) < 0))
  330.                 {
  331.                     strcpy(r->errmsg, "pcgiPutEnvironment() failed");
  332.                     fclose(f);
  333.                     return(-1);
  334.                 }
  335.  
  336.                 *p=0;
  337.                 p++;
  338.  
  339.                 if((strcmp(buf,"SOFTWARE_NAME"))==0)
  340.                 {  
  341.                     strcpy(r->sw_name, p);
  342.                 }
  343.                 else if((strcmp(buf,"SOFTWARE_HOME"))==0)
  344.                 {  
  345.                     strcpy(r->sw_home, p);
  346.                 }
  347.                 else if((strcmp(buf,"SOFTWARE_EXE"))==0)
  348.                 {  
  349.                     strcpy(r->sw_exe, p);
  350.                 }
  351.                 else if((strcmp(buf,"PCGI_CLOSE_FDS"))==0)
  352.                 {
  353.                     if ((pcgiAssignCloseFileDescriptors(r, p)) < 0)
  354.                         return(-1);
  355.                 }
  356.                 else if ((strcmp(buf,"PCGI_DISPLAY_ERRORS"))==0)
  357.                     r->displayErrors = pcgiTruthValue(p[0]);
  358.                 else if((strcmp(buf,"PCGI_ERROR_LOG"))==0)
  359.                 {  
  360.                     strcpy(r->errlog, p);
  361.                 }
  362.                 else if((strcmp(buf,"PCGI_EXE"))==0)
  363.                 {  
  364.                     strcpy(r->sw_exe, p);
  365.                 }
  366.                 else if((strcmp(buf,"PCGI_HOST"))==0)
  367.                 {  
  368.                     strcpy(r->sockhost, p);
  369.                 }
  370.                 else if((strcmp(buf,"PCGI_INSERT_PATH"))==0)
  371.                 {  
  372.                     strcpy(r->insertPath, p);
  373.                 }
  374.                 else if((strcmp(buf,"PCGI_MODULE_PATH"))==0)
  375.                 {  
  376.                     strcpy(r->modpath, p);
  377.                 }
  378.                 else if((strcmp(buf,"PCGI_NAME"))==0)
  379.                 {  
  380.                     strcpy(r->sw_name, p);
  381.                 }
  382.                 else if((strcmp(buf,"PCGI_PID_FILE"))==0)
  383.                 {  
  384.                     strcpy(r->procpath, p);
  385.                 }
  386.                 else if((strcmp(buf,"PCGI_PORT"))==0)
  387.                 {
  388.                     r->sockport = atoi(p);
  389.                 }
  390.                 else if((strcmp(buf,"PCGI_PUBLISHER"))==0)
  391.                 {  
  392.                     strcpy(r->pubpath, p);
  393.                 }
  394.                 else if((strcmp(buf,"PCGI_SOCKET_FILE"))==0)
  395.                 {  
  396.                     strcpy(r->sockpath, p);
  397.                 }
  398.                 else if((strcmp(buf,"PCGI_WORKING_DIR"))==0)
  399.                 {  
  400.                     strcpy(r->insertPath, p);
  401.                 }
  402.                 else if((strcmp(buf,"PYTHONPATH"))==0)
  403.                 {  
  404.                     strcpy(r->pythonPath, p);
  405.                 }
  406.  
  407.             }
  408.             else /* old-style (deprecated) directives */
  409.             {
  410.                 /* assume old style where the first four lines correspond to */
  411.                 /* 1. path of the socket file */
  412.                 /* 2. path of the process id file */
  413.                 /* 3. working directory (to be added to path by publisher) */
  414.                 /* 4. path of the module to be published */
  415.                 if (_newStyleDirectives)
  416.                 {
  417.                     strcpy(r->errmsg, "pcgi info file mixes old and new style directives (new style uses name=value)");
  418.                     fclose(f);
  419.                     return(-1);
  420.                 }
  421.                 if (oldStyleSocketFile == _oldStyleLineCount)
  422.                 {
  423.                     strcpy(r->sockpath, buf);
  424.                     pcgiPutNameValueInEnvironment("PCGI_SOCKET_FILE", buf);
  425.                 }
  426.                 else if (oldStyleProcessIdFile == _oldStyleLineCount)
  427.                 {
  428.                     strcpy(r->procpath, buf);
  429.                     pcgiPutNameValueInEnvironment("PCGI_PID_FILE", buf);
  430.                 }
  431.                 else if (oldStyleWorkDir == _oldStyleLineCount)
  432.                 {
  433.                     strcpy(r->insertPath, buf);
  434.                     if ((pcgiPutNameValueInEnvironment("PCGI_INSERT_PATH", buf)) < 0)
  435.                     {
  436.                         strcpy(r->errmsg, "pcgiPutNameValueInEnvironment() error");
  437.                         fclose(f);
  438.                         return(-1);
  439.                     }
  440.                 }
  441.                 else if (oldStyleModPath == _oldStyleLineCount)
  442.                 {
  443.                     strcpy(r->modpath, buf);
  444.                     if ((pcgiPutNameValueInEnvironment("PCGI_MODULE_PATH", buf)) < 0)
  445.                     {
  446.                         strcpy(r->errmsg, "pcgiPutNameValueInEnvironment() error");
  447.                         fclose(f);
  448.                         return(-1);
  449.                     }
  450.                 }
  451.                 else
  452.                 {
  453.                     strcpy(r->errmsg, "oldStyleLineCount exceeds maximum");
  454.                     fclose(f);
  455.                     return(-1);
  456.                 }
  457.                 _oldStyleLineCount++;
  458.             }     
  459.         }
  460.     }
  461.     fclose(f);
  462.  
  463.     /* 
  464.     //  Post-parsing work: decide if we have enough info to make it work. 
  465.     */
  466.  
  467.     /*
  468.     //  If the location of the publisher was not specified, try to
  469.     //  locate it.
  470.     */
  471.     if (!r->pubpath[0])
  472.     {
  473.         pcgiAssignPublisher(r);
  474.     }
  475.  
  476.     if (!r->pubpath[0])
  477.     {
  478.         strcpy(r->errmsg, "unable to determine the publisher location");
  479.         return(-1);
  480.     }
  481.     else
  482.     {
  483.         if (stat(r->pubpath, &statbuf) == -1)
  484.         {
  485.             sprintf(r->errmsg, "missing publisher: %s", r->pubpath);
  486.             return(-1);
  487.         }
  488.         else
  489.         {
  490.             if (!(statbuf.st_mode & S_IREAD))
  491.             {
  492.                 sprintf(r->errmsg, "publisher read error: %s", r->pubpath);
  493.                 return(-1);
  494.             }
  495.         }
  496.     }
  497.  
  498.     /*
  499.     //  Assign defaults, where necessary, for backward compatibility.
  500.     */
  501.     if (r->sw_name[0] && r->sw_home[0])
  502.     {
  503.         if (!r->sw_exe[0])
  504.         {
  505.             strcpy(r->sw_exe,"/usr/local/bin/python1.4");
  506.             pcgiPutNameValueInEnvironment("SOFTWARE_EXE", r->sw_exe);
  507.         }
  508.         if (!r->procpath[0])
  509.         {
  510.             sprintf(r->procpath,"%s/var/%s.pid", r->sw_home,r->sw_name);
  511.             pcgiPutNameValueInEnvironment("PCGI_PID_FILE", r->procpath);
  512.         }
  513.         if (!r->sockpath[0])
  514.         {
  515.             sprintf(r->sockpath,"%s/var/%s.soc", r->sw_home,r->sw_name);
  516.             pcgiPutNameValueInEnvironment("PCGI_SOCKET_FILE", r->sockpath);
  517.         }
  518.     }
  519.  
  520.     /*
  521.     // Other than r->pubpath, the other required attributes to complete
  522.     // the process are: r->procpath & r->sockpath.
  523.     */
  524.     if (!r->sockpath[0])
  525.     {
  526.         strcpy(r->errmsg, "missing parameter: PCGI_SOCKET_FILE");
  527.         return(-1);
  528.     }
  529.     if (!r->procpath[0])
  530.     {
  531.         strcpy(r->errmsg, "missing parameter: PCGI_PID_FILE");
  532.         return(-1);
  533.     }
  534.  
  535. /* Add this at a later date:  jhb - 8/10/98 */
  536. /*
  537.     if (r->sockport && !r->sockhost[0])
  538.     {
  539.         strcpy(r->errmsg, "unable to determine hostname, recommend specifying: PCGI_HOST");
  540.         return(-1);
  541.     }
  542. */
  543.     return(0);
  544. }
  545.  
  546. int pcgiPutEnvironment(char *buf)
  547. {
  548.     /*
  549.     // Stick a copy of the name=value pair in the
  550.     // process environment. Note that this would
  551.     // leak and need to be changed for any pcgi
  552.     // implementations that work as web server api
  553.     // extensions...
  554.     */
  555.     char *v = NULL;
  556.     if((v=malloc(strlen(buf) + sizeof(char))) == NULL)
  557.     {   
  558.         return(-1);
  559.     }
  560.     strcpy(v, buf);
  561.     if(putenv(v))
  562.     {   
  563.         return(-1);
  564.     }
  565.     return(0);
  566. }
  567.  
  568. int pcgiPutNameValueInEnvironment(char *name, char *value)
  569. {
  570.     /* 
  571.     //  Slight modification to pcgiPutEnvironment(), convenience function.
  572.     */
  573.     char *v = NULL;
  574.     if ((v=malloc(strlen(name) + strlen(value) + (2 * sizeof(char)))) == NULL)
  575.         return(-1);
  576.     sprintf(v, "%s=%s", name, value);
  577.  
  578.     if(putenv(v))
  579.         return(-1);
  580.     return(0);
  581. }
  582.  
  583. int pcgiTruthValue(char v)
  584. {
  585.     if (v=='1' || v=='t' || v=='T' || v=='y' || v=='Y') 
  586.         return 1; 
  587.     else if (v=='0' || v=='f' || v=='F' || v=='n' || v=='N') 
  588.         return 0;
  589.     else
  590.         return -1;
  591. }
  592.  
  593. #ifdef WIN32
  594. /*
  595.     This function lets both Unix & Win32 info files
  596.     to use the same '/' character as a path separator.
  597.     However it does this by assuming that we always
  598.     want '\' backslashes as path separators in a
  599.     Win32 environment.
  600. */
  601. void amendPathSeparators(char *src)
  602. {
  603.     char ch, *ptr;
  604.     ptr = src;
  605.     while ((ch = *src++))
  606.     {
  607.         if (ch == PATHSEP_UNIX) { *ptr = PATHSEP_WIN32; }
  608.         *ptr++;
  609.     }
  610. }
  611. #endif
  612.  
  613. #ifdef MAIN_PARSEINFO
  614. int main(int argc, char *argv[])
  615. {
  616.     /* char **env; */
  617.     pcgiResource resource;
  618.     pcgiResource *r = &resource;
  619.  
  620.     if (argc < 2)
  621.     {
  622.         printf("usage: parseinfo <pcgi-info-file>\n");
  623.         return(-1);
  624.     }
  625.  
  626. #ifdef CLOSE_FDS
  627.     CloseFileDescriptors = 1;
  628. #endif
  629.  
  630.     /* initialize pcgiResource */
  631.     memset(r,0,sizeof(pcgiResource));
  632.     r->conn=-1;
  633.  
  634.     strcpy(r->sw_info, argv[1]);
  635.     if ((pcgiParseInfo(r)) < 0)
  636.     {
  637.         printf("error parsing info file: %s\n", r->sw_info);
  638.         printf("  %s\n", r->errmsg);
  639.         return(-1);
  640.     }
  641.  
  642.     printf("pcgi resource attributes:\n");
  643.     printf("  %-20s %s\n", "r->sw_info", r->sw_info);
  644.     printf("  %-20s %s\n", "r->sw_name", r->sw_name);
  645.     printf("  %-20s %s\n", "r->sw_home", r->sw_home);
  646.     printf("  %-20s %s\n", "r->sw_exe", r->sw_exe);
  647.     printf("  %-20s %s\n", "r->procpath", r->procpath);
  648.     printf("  %-20s %s\n", "r->sockpath", r->sockpath);
  649.     printf("  %-20s %s\n", "r->modpath", r->modpath);
  650.     printf("  %-20s %s\n", "r->pubpath", r->pubpath);
  651.     printf("  %-20s %d\n", "r->procid", r->procid);
  652.     printf("  %-20s %s\n", "r->insertPath", r->insertPath);
  653.     printf("  %-20s %s\n", "r->pythonPath", r->pythonPath);
  654.     printf("  %-20s %d\n", "r->sockport", r->sockport);
  655.     printf("  %-20s %s\n", "r->sockhost", r->sockhost);
  656.     printf("  %-20s %d\n", "r->displayErrors", r->displayErrors);
  657.     printf("  %-20s %d\n", "CloseFileDescriptors", CloseFileDescriptors);
  658.     /* printf("\nenvironment:\n");         */
  659.     /* for (env=environ; *env != 0; env++) */
  660.     /*     printf("  %s\n", *env);         */
  661. }
  662. #endif
  663.